package cn.bellychang.ood.litejunit.v2.framework;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * @author ChangLiang
 * @date 2020/5/26
 */
public abstract class TestCase extends Assert implements Test {

    /**
     * 测试用例名字
     */
    private String name;

    public TestCase(String name) {
        this.name = name;
    }

    @Override
    public int countTestCases() {
        return 1;
    }

    @Override
    public void run(TestResult testResult){
        testResult.run(this);
    }


    public void doRun() throws Throwable {
        setUp();
        try {
            runTest();
        } finally {
            tearDown();
        }
    }

    public void setUp() {

    }

    public void tearDown() {

    }

    /**
     *
     * 这个方法原本由子类 即Command模式中的Receiver来实现
     * 但是发现这样每个{@link cn.bellychang.ood.litejunit.v1.framework.TestCase} subclass 只能写一个测试方法
     * 于是改用 可以被参数化以执行不同逻辑而无需子类化的单个类
     *
     */
    public void runTest() throws Throwable{
        Method runMethod = null;
        try {
            // 由于继承 这里是CalculatorTest#testAdd
            runMethod = getClass().getMethod(name, null);
        } catch (NoSuchMethodException e) {
            fail("Method \"" + name + "\" not found");
        }

        if (!Modifier.isPublic(runMethod.getModifiers())) {
            fail("Method \"" + name + "\" should be public");
        }

        try {
            runMethod.invoke(this, new Class[0]);
        } catch (IllegalAccessException e) {
            throw e;
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }
}
